package mysql8学习.高级.第15章_锁;

/**
 * ③自增锁(AUTO-INC锁)
 * 在使用MySQL过程中，我们可以为表的某个列添加 AUTO INCREMENT属性。
 * 所有插入数据的方式总共分为三类，分别是
 * 1.“Simple inserts”(简单插入)
 *   可以预先确定要插入的行数(当语句被初始处理时)的语句。
 *   包括没有嵌套子查询的单行和多行 INSERT.. .VALUES()和REPLACE语句。
 * 2.“Bulk inserts”(批量插入)
 *   事先不知道要插入的行数(和所需自动递增值的数量)的语句。
 *   比如 INSERT ... SELECT , REPLACE ... SELECT 和 LOAD DATA 语句,
 *   但不包括纯INSERT。InnoDB在每处理一行，为AUTO_INCREMENT列分配一个新值。
 * 3.“Mixed-mode inserts”(混合模式插入)
 *   这些是“Simple inserts'语句但是指定部分新行的自动递增值。
 *   例如INSERT INTO teacher (id, name) VALUES
 *   (1,'a')， (NULL,'b')， (5,'c')， (NULL,'d');
 *   只是指定了部分id的值。另一种类型的“混合模式插入”是
 *   INSERT ... ON DUPLICATE KEY UPDATE 。
 *
 * 对于上面数据插入的案例，MySQL中采用了自增锁的方式来实现，
 * AUTO-INC 锁是当向使用含有 AUTO_INCREMENT 列的表中插入数据时
 * 需要获取的一种特殊的表级锁，在执行插入语句时就在表级别加一个AUTO-INC锁，
 * 然后为每条待插入记录的AUTO_INCREMENT修饰的列分配递增的值，
 * 在该语句执行结束后，再把AUTO-INC锁释放掉。
 * 一个事务在持有AUTO-INC锁的过程中，其他事务的插入语句都要被阻塞，
 * 可以保证一个语句中分配的递增值 是连续的。
 * 也正因为此，其并发性显然并不高，
 * 当我们向一个有AUTO_INCREMENT关键字的主键插入值的时候，
 * 每条语句都要对这个表锁进行竞争，这样的并发潜力其实是很低下的，
 * 所以Innodb通过 innodb_autoinc_lock_mode
 * 的不同取值来提供不同的锁定机制，来显著提高SQL语句的可伸缩性和性能。
 *
 * innodb_autoinc_lock_mode有三种取值，分别对应与不同锁定模式:
 * (1) innodb_autoinc_lock_mode = 0("传统” 锁定模式)
 *      在此锁定模式下，""所有类型的insert语句都会获得一个特殊的表级AUTO-INC锁，""
 *      用于插入具有AUTO_INCREMENT列的表。
 *      即每当执行insert的时候，都会得到一个表级锁(AUTO-INC锁)，
 *      使得语句中生成的auto_increment为顺序，
 *      且在binlog中重放的时候,可以保证master与slave中数据的auto_increment是相同的。
 *      因为是表级锁，当在同一时间多个事务中执行insert的时候，对于AUTO-INC锁的争夺会限制并发能力。
 * (2) innodb_autoinc_lock_mode = 1("连续" 锁定模式)
 *      在MySQL 8.0之前，连续锁定模式是默认的。
 *      在这个模式下,“bulk inserts"仍然使用AUTO-INC表级锁，并保持到语句结束。
 *      这适用于所有 INSERT .. SELECT, REPLACE .. SELECT和LOAD DATA语句。
 *      同一时刻只有一个语句可以持有AUTO-INC锁。
 *      对于“simple inserts" (要指入的行数事先已知)，
 *      则通过在mutex (轻量锁)的控制下获得所需数量的自动递增值来避免表级AUTO-INC锁，
 *      它只在分配过程的持续时间内保持， 而不是直到语句完成。
 *      不使用表级AUTO-INC锁，除非AUTO-INC锁由另一个事务保持。
 *      如果另一个事务保持AUTO-INC锁，则 “Simple inserts“等待AUTO-INC锁，
 *      如同它是一个 "bulk inserts"。
 * (3) innodb_autoinc_lock_mode = 2("交错“锁定模式)
 *      保证了递增 但不连续，但是提高了并发性在此锁定模式下，
 *      自动递增值保证在所有并发执行的所有类型的insert语句中是唯一且单调递增的。
 *      但是，由于多个语句可以同时生成数字(即，跨语句交叉编号)
 *      为任何给定语句插入的行生成的值 可能不是连续的。
 *
 */
public class C_B1_3_自增锁 {
}